#
# Authors: Brian Skahan <bskahan@etria.com>
#          Tom von Schwerdtner <tvon@etria.com>
#
# Copyright 2004-2005, Etria, LLP
#
# This file is part of Quills
#
# Quills is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Quills is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Quills; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
###############################################################################

# Zope imports
from zope.interface import implements
from zope.component import getUtility
from AccessControl import ClassSecurityInfo
from Acquisition import aq_base

# Archetypes imports
from Products.Archetypes.public import BaseFolderSchema
from Products.Archetypes.public import Schema
from Products.Archetypes.public import TextField
from Products.Archetypes.public import TextAreaWidget
from Products.Archetypes.public import BaseFolder
from Products.Archetypes.public import registerType

from Products.Archetypes.Marshall import PrimaryFieldMarshaller

# Plone imports
from Products.CMFCore.utils import getToolByName
from plone.i18n.normalizer.interfaces import IIDNormalizer

# Quills imports
from quills.core.interfaces import IWeblog
from quills.app.topic import TopicContainer
from quills.app.topic import AuthorContainer
from quills.app.archive import ArchiveContainer
from quills.app.weblogentrybrain import WeblogEntryCatalogBrain
from quills.app.weblog import WeblogMixin

# Local imports
import config
import permissions as perms


# This won't work because the `weblog' object is not aq-wrapped, so it's not
# possible to use invokeFactory.
#def weblogTopicImageFolderSetup(weblog, event):
#    has_topic_images = hasattr(aq_base(weblog), 'topic_images')
#    # Create folder to store topic images
#    if config.CREATE_TOPIC_IMAGES_FOLDERS and not has_topic_images:
#        weblog.invokeFactory('Folder', id='topic_images', title='Topic Images')


WeblogSchema = BaseFolderSchema.copy() + Schema((

    # This is sort of cheating.  We are stealing the Dublin Core 'description'
    # field for our purposes, but then I don't seen any reason to duplicate the
    # information.
    TextField('description',
        searchable=1,
        accessor="Description",
        widget=TextAreaWidget(
            label='Description',
            description="""A brief description of this weblog.  This text will
            be displayed at the top of the page before any weblog entries.""",
            label_msgid="label_weblog_description",
            description_msgid="help_weblog_description",
            i18n_domain="quills"),
        ),
    ),
    marshall=PrimaryFieldMarshaller(),
    )
# The subject is not language-specific
WeblogSchema['subject'].languageIndependent = True


class Weblog(WeblogMixin, BaseFolder):
    """Weblog object.

    >>> from zope.interface.verify import verifyClass
    >>> verifyClass(IWeblog, Weblog)
    True
    """

    implements(IWeblog)

    schema = WeblogSchema
    security = ClassSecurityInfo()

    _at_rename_after_creation = True

    def at_post_create_script(self):
        has_topic_images = hasattr(aq_base(self.aq_inner), 'topic_images')
        # Create folder to store topic images
        if config.CREATE_TOPIC_IMAGES_FOLDERS and not has_topic_images:
            self.invokeFactory('Folder', id='topic_images', title='Topic Images')

    security.declareProtected(perms.View, 'getTopics')
    def getTopics(self):
        """See IWeblog.
        """
        topic_container = TopicContainer('topics').__of__(self)
        return topic_container.getTopics()

    security.declareProtected(perms.View, 'getTopicById')
    def getTopicById(self, id):
        """See IWeblog.
        """
        topic_container = TopicContainer('topics').__of__(self)
        return topic_container.getTopicById(id)

    security.declareProtected(perms.View, 'getArchives')
    def getArchives(self):
        """See IWeblog.
        """
        # XXX 'archive' should not be hard-wired here.
        return ArchiveContainer('archive').__of__(self)

    security.declareProtected(perms.View, 'getEntries')
    def getEntries(self, maximum=None, offset=0):
        """See IWeblog.
        """
        catalog = getToolByName(self, 'portal_catalog')
        catalog._catalog.useBrains(WeblogEntryCatalogBrain)
        path = '/'.join(self.getPhysicalPath())
        results = catalog(
                meta_type=['WeblogEntry',],
                path={'query':path, 'level': 0},
                sort_on = 'effective',
                sort_order = 'reverse',
                review_state = 'published')
        return self._filter(results, maximum, offset)

    security.declareProtected(perms.ViewDrafts, 'getAllEntries')
    def getAllEntries(self, maximum=None, offset=0):
        """See IWeblog.
        """
        catalog = getToolByName(self, 'portal_catalog')
        catalog._catalog.useBrains(WeblogEntryCatalogBrain)
        path = '/'.join(self.getPhysicalPath())
        results = catalog(
                meta_type=['WeblogEntry',],
                path={'query':path, 'level': 0},
                sort_on = 'effective',
                sort_order = 'reverse')
        return self._filter(results, maximum, offset)

    security.declareProtected(perms.ViewDrafts, 'getDrafts')
    def getDrafts(self, maximum=None, offset=0):
        """See IWeblog.
        """
        catalog = getToolByName(self, 'portal_catalog')
        catalog._catalog.useBrains(WeblogEntryCatalogBrain)
        path = '/'.join(self.getPhysicalPath())
        results = catalog(
                meta_type=['WeblogEntry',],
                path={'query':path, 'level': 0},
                sort_on = 'effective',
                sort_order = 'reverse',
                review_state = 'private')
        return self._filter(results, maximum, offset)

    security.declareProtected(perms.View, 'getAuthors')
    def getAuthors(self):
        """See IWeblog.
        """
        author_container = AuthorContainer('authors').__of__(self)
        return author_container.getAuthors()

    security.declareProtected(perms.View, 'getAuthorById')
    def getAuthorById(self, id):
        """See IWeblog.
        """
        author_container = AuthorContainer('authors').__of__(self)
        return author_container.getAuthorById(id)

    security.declareProtected(perms.AddContent, 'addEntry')
    def addEntry(self, title, excerpt, text, topics=[], id=None, pubdate=None, mimetype=None):
        """See IWeblog.
        """
        if id is None:
            id = getUtility(IIDNormalizer).normalize(title)
        self.invokeFactory(id=id, type_name='WeblogEntry')
        entry = getattr(self, id)
        entry.setTitle(title)
        # if no mimetype was specified, we use the default
        if mimetype is None:
            mimetype = entry.getMimeType()
        entry.setText(text, mimetype=mimetype)
        entry.setExcerpt(excerpt)
        if topics:
            entry.setTopics(topics)
        if pubdate is not None:
            entry.setPublicationDate(pubdate)
        entry.reindexObject()
        return entry

    security.declareProtected(perms.DeleteContent, 'deleteEntry')
    def deleteEntry(self, entry_id):
        """See IWeblog.
        """
        self.manage_delObjects(ids=[entry_id,])

    security.declareProtected(perms.View, 'getAuthorById')
    def getWeblogContentObject(self):
        """See IWeblog.
        """
        return self

    security.declareProtected(perms.View, 'getAuthorById')
    def getWeblog(self):
        """See IWeblog.
        """
        return self

registerType(Weblog, config.PROJECTNAME)
